#ifndef PR_15_20_HPP
#define PR_15_20_HPP

#include <iostream>

using namespace std;

class Base
{
public:
    void pub_mem();
protected:
    int prot_mem;
private:
    char priv_mem;
};

struct Pub_Derv : public Base
{
    int f() { return prot_mem; }
    void memfcn(Base &b)
    {
        b = *this;
        cout << "Pub_Derv" << endl;
    }
};

struct Priv_Derv : private Base
{
    int f1() const { return prot_mem; }
    void memfcn(Base &b)
    {
        b = *this;
        cout << "Priv_Derv" << endl;
    }
};

struct Prot_Derv : protected Base
{
    int f2() { return prot_mem; }
    void memfcn(Base &b)
    {
        b = *this;
        cout << "Prot_Derv" << endl;
    }
};

struct Derived_from_Public : public Pub_Derv
{
    int use_base() { return prot_mem; }
    void memfcn(Base &b)
    {
        b = *this;
        cout << "Derived_from_Public" << endl;
    }
};

struct Derived_from_Protected : protected Prot_Derv
{
    int use_base() { return prot_mem; }
    void memfcn(Base &b)
    {
        b = *this;
        cout << "Derived_from_Protected" << endl;
    }
};

struct Derived_from_Private : private Pub_Derv
{
    void memfcn(Base &b)
    {
        cout << "Derived_from_Private" << endl;
    }
};

int pr_15_20()
{
    Pub_Derv d1;
    Priv_Derv d2;
    Prot_Derv d3;
    Derived_from_Public dd1;
    Derived_from_Private dd2;
    Derived_from_Protected dd3;

    Base base;
    Base *p = new Base;
    p = &d1;    // d1 的类型是 Pub_Derv
//    p = &d2;    // d2 的类型是 Priv_Derv
//    p = &d3;    // d3 的类型是 Prot_Derv
    p = &dd1;   // dd1 的类型是 Derived_from_Public
//    p = &dd2;   // dd1 的类型是 Derived_from_Private
//    p = &dd3;   // dd1 的类型是 Derived_from_Protected

    d1.memfcn(base);
    d2.memfcn(base);
    d3.memfcn(base);
    dd1.memfcn(base);
//    dd2.memfcn(base);
    dd3.memfcn(base);
    return 0;
}

#endif // PR_15_20_HPP
